from loa_game import *
from math import sqrt
from time import time


N = Direction("N", (-1, 0)) 
E = Direction("E", (0, 1)) 
S = Direction("S", (1, 0)) 
W = Direction("W", (0, -1)) 
NE = Direction("NE", (-1, 1)) 
SE = Direction("SE", (1, 1)) 
SW = Direction("SW", (1, -1)) 
NW = Direction("NW", (-1, -1))

def square(state):
    
    player = state.getCurrentPlayer()
    other = otherp(player)
    
    p = {'top': state.size, 'bottom': -1, 'left': state.size, 'right': -1}
    o = dict(p)
    dic = {player:p, other: o}
    board = state.board
    
    for line in range(state.size):
        for row in range(line):
            if board[line][row] == player: current = dic[player] 
            elif board[line][row] == other:  current = dic[other]
            else: continue
            if line < current['top']: current['top'] = line
            if line > current['bottom']: current['bottom'] = line 
            if row < current['left']: current['left'] = row
            if row > current['right']: current['right'] = row 

    """        
    print 'going to return'
    print 'player'
    print 'bottom:    ', dic[player]['bottom']
    print 'top:    ', dic[player]['top']
    print 'left    :', dic[player]['left']
    print 'right    :', dic[player]['right']
    """
    return (
            ((dic[other]['bottom']-dic[other]['top'])*(dic[other]['right']-dic[other]['left'])+1)
            /
            ((dic[player]['bottom']-dic[player]['top'])*(dic[player]['right']-dic[player]['left'])+1)
            )
            
        

def otherp(p):
    if p == BLACK: return WHITE
    return BLACK

def get_con(state):
    
    con = {BLACK:{}, WHITE:{}}
    
    board = enumerate(state.board)
    for line in board:
    
        for cell in enumerate(line[1]):
            
            if cell[1] is not EMPTY: 
                player = cell[1]
            
                comp = state._getConnectiveComponent(line[0], cell[0], player).__repr__()
                
                try:
                    con[player][comp] += 1
                except KeyError:
                    con[player][comp] = 1

    return con

def num_con(state):
    con = get_con(state)
    player = state.getCurrentPlayer()
    other = otherp(player)
    return 1.0*len(con[other])/len(con[player])

def variance(state):
    
    con = get_con(state)
    player = state.getCurrentPlayer()
    other = otherp(player)
    
    sum_p = 0
    for i, v in con[player].items():
        for j, u in con[player].items():
            if i != j:
                E = v+u
                E2 =  sum(map(lambda x: x**2, [v,u]))
                sum_p += E2-E**2
                
    sum_o = 0
    for i, v in con[other].items():
        for j, u in con[other].items():
            if i != j:
                E = v*u
                E2 =  sum(map(lambda x: x**2, [v,u]))
                sum_o += E2-E**2
    
    return abs(sum_p*1.0)/abs(sum_o)
            
def glob_sum_dis(state):          
    
    def dis(i,j, k,l):
        return sqrt(abs(i-k)**2+abs(j-l)**2)
    
    def sum_dis(board, player, i,j):          
        board = enumerate(board)
        
        sum = 0
        for line in board:
        
            for cell in enumerate(line[1]):
                
                if cell[1] is player:
                    sum += dis(i,j,line[0],cell[0])
        return sum/state.size**2

    player = state.getCurrentPlayer()
    other = otherp(player)
    board = enumerate(state.board)
    sum_p = 0
    sum_o = 0
    for line in board:
    
        for cell in enumerate(line[1]):
            
            if cell[1] is player:
                sum_p += sum_dis(state.board, player, line[0], cell[0])
            if cell[1] is other:
                sum_o += sum_dis(state.board, other, line[0], cell[0])
    return sum_p/sum_o

def alot(state):
    return glob_sum_dis(state) + variance(state) + num_con(state)

def t(game):
    
    r = {}
    for f in [num_con, variance, glob_sum_dis]:
        
        start = time()
        f(game)
        end = time()
        
        r[repr(f).split()[1]]=end-start
    return r




"""
game = LinesOfActionState(8,8)            
print t(game)
game = game._getMoveAction( 0, 6, Direction("S", (1, 0)))[1]
game = game._getMoveAction( 1, 0, Direction("S", (1, 0)))[1]
game = game._getMoveAction( 0, 1, Direction("S", (1, 0)))[1]
game = game._getMoveAction( 7, 0, Direction("N", (-1, 0)))[1]
game = game._getMoveAction( 0, 3, Direction("S", (1, 0)))[1]
game = game._getMoveAction( 6, 0, Direction("N", (-1, 0)))[1]
game = game._getMoveAction( 7, 2, N)[1]

print t(game)
"""
